package com.iot.inter.entity.newpojo;

import com.iot.inter.entity.newpojo.request.RequestHeader;
import com.iot.inter.utils.JaxbUtil;
import com.iot.inter.utils.SignUtil;
import com.iot.inter.utils.TimeUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
 * Demo 拼装xml报文的工具类
 *
 * @author lm
 * @date 2018/08/31
 */
public class TurntoInterfaceUtils {


    /**
     * 请求header信息拼装
     *
     * @param cmdType
     * @return
     */
    public RequestHeader getRequestHeader(String cmdType, String accessCode) {

        RequestHeader rHeader = new RequestHeader();
        rHeader.setVersion(Constant.VERSION);
        rHeader.setAccessCode(accessCode);
        rHeader.setCmdType(cmdType);
        //返回响应时的UTC时间戳（秒），和互联网时间误差不能超过 5 分钟。
        rHeader.setTimestamp(TimeUtil.getTimeInMillis().toString());
        return rHeader;
    }

    /**
     * 对head和body进行签名
     *
     * @param head
     * @param body
     * @return
     */
    public String getSign(RequestHeader head, Object body, Class cls, String secret) throws Exception {

        // 对head进行xml编码，并去除xml头信息
        JaxbUtil jaxbUtil = new JaxbUtil(RequestHeader.class);
        String sHead = jaxbUtil.toXml(head, "utf-8");
        sHead = sHead.substring(sHead.indexOf("<head>"));
        // 对body进行xml编码，并去除xml头信息
        JaxbUtil jaxbUti2 = new JaxbUtil(cls);
        String sBody = jaxbUti2.toXml(body, "utf-8");
        sBody = sBody.substring(sBody.indexOf("<body>"));

        sBody = orgSignContent(sortNode(sBody, "body/*"), "body");
        sHead = orgSignContent(sortNode(sHead, "head/*"), "head");
        // 对head+body内容进行签名，并返回结果
        //System.out.println("签名内容是：" + sHead + sBody);
        return SignUtil.generateSign(sHead + sBody, secret);
        //return SignUtil.generateSign(sHead + sBody, Constant.SECRET);
    }

    private Map<String, String> sortNode(String xml, String path) throws Exception {
        Document doc = DocumentHelper.parseText(xml);
        @SuppressWarnings("unchecked")
        List<Node> list = doc.selectNodes(path);
        Map<String, String> map = new TreeMap<String, String>();
        for (Node node : list) {
            map.put(node.getName(), node.getText());
        }
        return map;
    }

    private String orgSignContent(Map<String, String> childNodes, String nodeName) {
        StringBuffer requestStr = new StringBuffer("");
        requestStr.append("<").append(nodeName).append(">");
        for (Entry<String, String> entry : childNodes.entrySet()) {
            requestStr.append("<").append(entry.getKey()).append(">").append(entry.getValue()).append("</").append(entry.getKey()).append(">");
        }
        requestStr.append("</").append(nodeName).append(">");
        return requestStr.toString();
    }


}
